/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import org.zhiqim.kernel.annotation.AnNullable;

/**
 * Windows相关工具类
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class Windows
{
    /***************************************************************/
    //CMD命令操作
    /***************************************************************/
    
    /**
     * 执行Windows的命令，无返回结果，调用cmd /c
     * 
     * @param cmd           命令行
     * @throws IOException  异常
     */
    public static void cmdNotResult(String cmd) throws IOException
    {
        Asserts.as(Systems.isWindows()?null:"不是Windows系统，不支持调用CMD命令");
        Runtime.getRuntime().exec(new String[]{"cmd", "/c", cmd});
    }
    
    /**
     * 执行CMD的命令，返回字符串列表，调用cmd /c
     * 
     * @param cmd           命令行
     * @return              返回指定的字符串
     * @throws IOException  异常
     */
    public static String cmd(String cmd) throws IOException
    {
        Asserts.as(Systems.isWindows()?null:"不是Windows系统，不支持调用CMD命令");
        return Runtimes.exec(new String[]{"cmd", "/c", cmd});
    }
    
    /**
     * 执行CMD的命令，返回字符串列表，调用cmd /c
     * 
     * @param cmd           命令行
     * @param encoding      指定编码
     * @return              返回指定的字符串
     * @throws IOException  异常
     */
    public static String cmd(String cmd, String encoding) throws IOException
    {
        Asserts.as(Systems.isWindows()?null:"不是Windows系统，不支持调用CMD命令");
        return Runtimes.exec(new String[]{"cmd", "/c", cmd}, Charset.forName(encoding));
    }
    
    /**
     * 执行CMD的命令，返回字符串列表，调用cmd /c
     * 
     * @param cmd           命令行
     * @param encoding      编码
     * @param maxLineNum    返回行数,0表示所有行,>0表示返回该行数即结束
     * @throws IOException  异常
     */
    public static List<String> cmd(String cmd, String encoding, int maxLineNum) throws IOException
    {
        Asserts.as(Systems.isWindows()?null:"不是Windows系统，不支持调用CMD命令");
        return Runtimes.exec(new String[]{"cmd", "/c", cmd}, encoding, maxLineNum);
    }
    
    /***************************************************************/
    //CMD命令操作下的命令
    /***************************************************************/
    
    /**
     * 执行copy命令，得到结果字符串
     * 
     * @param arguments     参数
     * @param src           源地址
     * @param dest          目标地址
     * @param encoding      编码
     * @return              命令结果集
     * @throws IOException  IO异常
     */
    public static String copy(String arguments, String src, String dest) throws IOException
    {
        StringBuilder strb = new StringBuilder("copy ");
        if (Validates.isNotEmpty(arguments))
            strb.append(arguments).append(" ");
        
        strb.append(src).append(" ").append(dest);
        return cmd(strb.toString());
    }
    
    /**
     * 执行ipconfig命令，得到结果字符串
     * 
     * @param arguments     参数
     * @param encoding      编码
     * @return              命令结果集
     * @throws IOException  IO异常
     */
    public static String ipconfig(String arguments) throws IOException
    {
        return cmd(Validates.isEmpty(arguments)?"ipconfig":"ipconfig "+arguments);
    }
    
    /**
     * 获取第一个MAC地址，结果为null表示未找到
     * 
     * @return              MAC地址
     * @throws IOException  IO异常
     */
    @AnNullable
    public static String getFirstMacAddress() throws IOException
    {
        String result = Runtimes.exec(new String[]{"cmd", "/c", "ipconfig /all"});
        
        String[] lines = Arrays.toStringArray(result, "\n");
        for(String line : lines)
        {      
            line = line.trim();

            if (line.indexOf("Physical Address") >= 0 || line.indexOf("物理地址") >= 0)
            {
                String mac = line.substring(line.length() - 17);
                if (Strings.getTimes(mac, '-') == 5)
                    return mac.replaceAll("-", ":").toLowerCase();
            }
        }
        
        //未找到物理地址
        return null;
    }
}
